home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
database
/
cbin
/
cbin.txt
< prev
next >
Wrap
Text File
|
1987-07-06
|
13KB
|
382 lines
The CBIN package is a small collection of BIN routines that
can be LOADed and CALLed by dBase III Plus. They also work with
FoxBase+. The name "CBIN" comes from the fact that the routines are
written, not in assembler as in usual for BIN routines, but in the C
programming language. Russell Freeland modified the start-up code
for Wizard C to work with dBase; Andrew Schulman wrote much of the
C code.
Whereas large packages such as dBase Tools for C or Tom
Rettig's Library require that you load (and learn!) a large software
package simply in order to perform a few functions, the CBIN routines
operate independently of one another. Learn and load the ones you
need, and you don't have to bother with a 100K memory-resident
program hogging your PC's memory.
For more information, contact either:
Andrew Schulman Russell Freeland
12 Humboldt Street 1780 SW 43
Cambridge MA 02140 Fort Lauderdale FL 33064
We would appreciate hearing from you: bug reports would be
particularly appreciated right now. Also, suggestions for other BIN
routines that you would find useful in your everyday work. Finally,
any monetary contribution you could make would be appreciated. We have
big plans for more CBIN utilities, so it's worth your while to become
a CBIN supporter.
In the following descriptions of the BIN routines, note that
all BINs must be LOADed into dBase III Plus before they can be
CALLed. You can do a RELEASE MODULE when you are done with it.
Also note that some of the BIN files have to be called twice:
once to "seed" them with necessary information they need, and again
to get back the information you need.
WRITE: Write characters to file or to printer (even chr(0))
-----
Setup: F = "<filename> <mode>[+]"
CALL WRITE WITH F
<filename> : any valid DOS filename or PRN: (for printer)
<mode> : x (for hexadecimal)
d (for decimal)
[+] : optional + sign indicates append to file, not overwrite
Return from setup:
if F = "-1" then file could not be opened; otherwise F will
contain DOS file handle, e.g., "04"
Use (after setup):
CALL WRITE WITH "<bytes...>"
<bytes>: if hexadecimal mode was selected, hex designation
for characters; if decimal mode was selected, chr()
designation.
Multiple occurrences of characters are designated
with (bytes,number), where number will always be a
decimal count.
Strings (cannot include spaces) are delimited with
apostrophes: 'hello'
(See examples below)
Close file:
CALL WRITE WITH "(!)"
Examples:
To create a DBF file without using CREATE (more useful
DBF files can then be constructed using COPY TO STRUCTURE EXTENDED
and CREATE FROM commands):
LOAD WRITE
F = "FOO.DBF X"
CALL WRITE WITH F && open the file
IF (F <> "-1") && check if okay
* write characters out to file
CALL WRITE WITH "3 (0,7) 41 0 4f (0,21) 46 (4f,2) (0,8)"
CALL WRITE WITH "43 (0,4) 4e (0,15) d 1a"
ENDIF
CALL WRITE WITH "(!)" && close the file
USE FOO && do something with it
Note that even though FOO.DBF was opened in hex mode,
(0,21) writes 21 copies of chr(0) out to the file, not 33. In hex
mode, only the characters themselves are in hex; counts are always in
decimal.
To set an Epson printer to italic, print the word "Hello" and
return to roman (does not work in FoxBase+):
CALL WRITE WITH "PRN: X"
CALL WRITE WITH "1b '4' 'Hello' 1b '5' (!)"
READ: Read a character from a file
----
Setup: F = "<filename>"
CALL READ WITH F
<filename>: : any valid DOS filename
No value returned by setup.
To call (after setup):
C = SPACE(1)
CALL READ WITH C
Return from call:
The next available character in file is returned in
passed variable. If end-of-file is reached, or otherwise
character can not be retrieved, chr(255) is returned.
Close file: CALL READ WITH CHR(255)
Problems: That READ is not parallel to WRITE is clearly a problem.
This will be fixed in future versions. This version simply
illustrates that you can have relatively fast character-at-a-
time access to files from within dBase. Future versions
will let you access multiple characters at a time, and will
allow you to retrieve the next word from a file (similar to
the C function strtok()).
Examples:
* TESTREAD.PRG
PARAMETER FILE
LOAD READ
CALL READ WITH "&FILE" && open the file
? UPPER(FILE)
?
C = SPACE(1)
DO WHILE (C <> CHR(255)) && while not end-of-file
CALL READ WITH C && get a char into C
?? C && display it
ENDDO
CALL READ WITH CHR(255) && close the file
DO TESTREAD WITH "CBIN.TXT" && display this file
This example merely displays a file on the screen.
Presumably you would want to do something with the characters inside the
do-while loop, other than just display them.
PEEK: Examine PC memory
----
To call: M = "<segment> <offset> [count]"
CALL PEEK WITH M
<segment>:<offset> : address
[count] : optional number of bytes to retrieve
Return from call:
After calling PEEK, M will contain the contents of
PC memory address segment:offset. The number of bytes
depends retrieved depends on the optional [count]
parameter AND ON THE LENGTH OF THE STRING PASSED IN.
Note that the information retrieved overwrites the
information passed in. It is assumed that the information
passed in is needed by the routine, not by the user.
Problems and Comments:
PEEK is very limited right now, as you need routines
to retrieve valid addresses for you that can then be
passed to PEEK. PEEK should have a "mode" in which the
information retrieved for you is returned in a form
that can then be passed back to PEEK. Any decent book
on BASIC gives many illustrations of the wonderful
non-portable tricks that can be done with a properly-
written PEEK.
Valid dBase addresses can be retrieved with VARPTR.
(See below)
Example:
M = "68c1 d 11"
CALL PEEK WITH M
? M
"Hello world"
POKE : Fondle PC memory
----
To call: CALL POKE WITH "<segment> <offset> <bytes...> [switch]"
<segment>:<offset> : address
<bytes...> : arbitrary number of bytes
[switch] : optional: -d means that <bytes...> are in
decimal, -a means ascii, default is hex.
(See examples)
No value returned by call.
Problems and Comments:
POKE suffers from the same problems as PEEK.
Also note that PEEK and READ should be very similar
in operation; and that POKE and WRITE should match
each other as well.
Example: The following examples all POKE "Hello" into the
same address in memory:
CALL POKE WITH "68c1 d 48 65 6c 6c 6e"
CALL POKE WITH "68C1 000D H E L L O -A"
CALL POKE WITH "68c1 000d 72 101 108 108 111 -d"
Note that even when the <bytes...> are in decimal, addresses
are always in hexadecimal. This is the convention in
addressing memory.
VARPTR -- Take address of dBase variable
------
Setup: X = <dBase memvar>
CALL VARPTR WITH X
No value returned by setup.
To use: Y = <storage for return value>
CALL VARPTR WITH Y
Notes: The segment returned is dBase's data segment.
The dBase III Plus memvar symbol table can be found
near <segment>:0004 (however, this is not the case
in FoxBase+).
Example:
X = "Hello world"
CALL VARPTR WITH X
Y = SPACE(10)
CALL VARPTR WITH Y
? Y
68c1 d
Y = y + " 11" + SPACE(5)
CALL PEEK WITH Y
? Y
Hello world
INTER -- do DOS or BIOS interrupt from dBase (yow!)
-----
To use: Using this one is complex enough that a dBase PRG
front end, INTER.PRG, has been provided. If you
want to call INTER.BIN directly, see how INTER.PRG
is coded. Otherwise, just call INTER.PRG or include
it in your standard procedure file. The syntax for
call INTER.PRG is:
DO INTER WITH INTNO,AX,BX,CX,DX
Note: Remember that if one of the "high" registers must be
loaded (for instance, BH), the value must be multiplied
by 256. See the sample program, TESTINT.PRG
Return: See the sample program, TESTINT.PRG
BEEP -- Sound the PC speaker
----
To use: CALL BEEP WITH <pitch>,<duration>
Notes: See the sample program, BACH.PRG, for an example
of how to call beep. The Bach transcription into
computer gibberish comes, more or less, from the
Framework II Developer's Toolkit. The BEEP routines
were derived from routines published in the February
1987 PC TECH JOURNAL with important corrections in
the July 1987 letters column.
RAND -- Generate pseudorandom number
----
Setup: X = <dBase NUMERIC memory variable>
CALL RAND WITH X
To use: X = <dBase NUMERIC memory variable>
CALL RAND WITH X
Notes: Unlike the other BIN routines, RAND takes and
returns a single dBase numeric memory variable,
and NOT its string representation.
Example:
. load rand
. seed = val(substr(time(),7,2))
. call rand with seed
. x = 0
. call rand with x
. ? x
346
. call rand with x
. ? x
130
. call rand with x
. ? x
10982
. call rand with x
. ? x
1090
FILEFIND -- Wildcard searches for files, directories
--------
Setup: F = "(!)<pattern> <attribute> <extra space>"
CALL FILEFIND WITH F
To use: F = "<enough space to hold file name>"
CALL FILEFIND WITH F
Notes: Each time you call FILEFIND, it will retrieve
the next DOS file matching the pattern with which
you "seeded" it. To tell FILEFIND you're starting
"seeding" a new pattern, preface with pattern with
"(!)".
The attributes are passed as string representations
of the following numbers:
0 - normal files
1 - read-only files
2 - hidden files
4 - system files
8 - volume label
16 - directory
32 - archive
Example: F = "\*.* 16" + SPACE(15)
CALL FILEFIND WITH F
DO WHILE (F <> "-1") && until the well runs dry...
? F
F = SPACE(15)
CALL FILEFIND WITH F
ENDDO
This finds all directories and normal files off
the main root.
F = "(!)" + "*.BIN" + STR(0) + SPACE(15)
DO WHILE (F <> "-1")
? F
F = SPACE(15)
CALL FILEFIND WITH F
ENDDO
Can you figure out what this does?
SRCHPATH -- Search DOS path for file
--------
See Russell's SRCHPATH.PRG, and all will be revealed unto you.
-- Andrew Schulman
6 July 1987
P.S. Again the authors of CBIN implore you to send feedback
and/or contributions.